"""
分析服务模块基础架构
提供统一的分析功能和数据处理接口
"""
from abc import ABC, abstractmethod
from typing import Dict, Any, List, Optional, Union
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy import func, desc, and_, or_
import json
from decimal import Decimal

from core.database import get_db
from core.logging_config import get_logger
from models.analysis_task import AnalysisTask
from models.petition_record import (
    RegionalAnalysisResult,
    ComplaintTypeAnalysisResult,
    SentimentAnalysisResult,
    ComplianceAnalysisResult,
    DuplicateAnalysisResult
)

# 日志记录器
logger = get_logger("analysis_service")


class AnalysisFilters:
    """分析过滤器基类"""

    def __init__(self):
        self.task_id: Optional[int] = None
        self.start_date: Optional[datetime] = None
        self.end_date: Optional[datetime] = None
        self.region: Optional[str] = None
        self.status: Optional[str] = None
        self.limit: Optional[int] = None
        self.offset: Optional[int] = 0

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "task_id": self.task_id,
            "start_date": self.start_date.isoformat() if self.start_date else None,
            "end_date": self.end_date.isoformat() if self.end_date else None,
            "region": self.region,
            "status": self.status,
            "limit": self.limit,
            "offset": self.offset
        }


class AnalysisResult:
    """分析结果基类"""

    def __init__(self, success: bool = True, data: Any = None, message: str = "success"):
        self.success = success
        self.data = data
        self.message = message
        self.timestamp = datetime.now()

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "success": self.success,
            "data": self.data,
            "message": self.message,
            "timestamp": self.timestamp.isoformat()
        }


class BaseAnalyzer(ABC):
    """基础分析器抽象类"""

    def __init__(self, db: Session):
        self.db = db
        self.logger = logger

    @abstractmethod
    def get_model_class(self):
        """获取数据模型类"""
        pass

    @abstractmethod
    def analyze_data(self, filters: AnalysisFilters) -> AnalysisResult:
        """分析数据的核心方法"""
        pass

    def build_base_query(self, filters: AnalysisFilters):
        """构建基础查询"""
        query = self.db.query(self.get_model_class())

        # 应用任务筛选
        if filters.task_id:
            query = query.filter(self.get_model_class().task_id == filters.task_id)

        # 应用时间筛选
        if filters.start_date:
            query = query.filter(self.get_model_class().created_at >= filters.start_date)
        if filters.end_date:
            query = query.filter(self.get_model_class().created_at <= filters.end_date)

        # 应用其他筛选条件
        if hasattr(filters, 'region') and filters.region:
            query = self._apply_region_filter(query, filters.region)

        return query

    def _apply_region_filter(self, query, region: str):
        """应用区域筛选（子类可重写）"""
        return query

    def get_basic_statistics(self, filters: AnalysisFilters) -> Dict[str, Any]:
        """获取基础统计信息"""
        query = self.build_base_query(filters)

        total_count = query.count()

        # 今日新增
        today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
        today_count = query.filter(
            self.get_model_class().created_at >= today_start
        ).count()

        # 本周新增
        from datetime import timedelta
        week_start = today_start - timedelta(days=today_start.weekday())
        week_count = query.filter(
            self.get_model_class().created_at >= week_start
        ).count()

        # 本月新增
        month_start = today_start.replace(day=1)
        month_count = query.filter(
            self.get_model_class().created_at >= month_start
        ).count()

        return {
            "total_count": total_count,
            "today_count": today_count,
            "week_count": week_count,
            "month_count": month_count,
            "growth_rate": self._calculate_growth_rate(total_count, month_count)
        }

    def _calculate_growth_rate(self, total_count: int, month_count: int) -> float:
        """计算增长率"""
        if month_count == 0:
            return 0.0
        # 简化的增长率计算
        return round((month_count / max(total_count, 1)) * 100, 2)

    def get_time_series_data(self, filters: AnalysisFilters, granularity: str = 'day') -> List[Dict[str, Any]]:
        """获取时间序列数据"""
        query = self.build_base_query(filters)

        # 根据粒度分组
        if granularity == 'day':
            group_by = func.date(self.get_model_class().created_at)
        elif granularity == 'week':
            group_by = func.strftime('%Y-%W', self.get_model_class().created_at)
        elif granularity == 'month':
            group_by = func.strftime('%Y-%m', self.get_model_class().created_at)
        else:
            group_by = func.date(self.get_model_class().created_at)

        results = query.with_entities(
            group_by.label('date'),
            func.count().label('count')
        ).group_by(group_by).order_by(group_by).all()

        return [
            {
                "date": result.date,
                "count": result.count
            }
            for result in results
        ]

    def get_top_items(self, filters: AnalysisFilters, limit: int = 10) -> List[Dict[str, Any]]:
        """获取排名前N的项目（子类可重写）"""
        return []

    def validate_filters(self, filters: AnalysisFilters) -> bool:
        """验证过滤器"""
        if filters.start_date and filters.end_date:
            if filters.start_date > filters.end_date:
                raise ValueError("开始时间不能晚于结束时间")
        return True


class AnalysisService:
    """统一分析服务"""

    def __init__(self, db: Session):
        self.db = db
        self.analyzers = {}
        self.logger = logger

    def register_analyzer(self, name: str, analyzer_class):
        """注册分析器"""
        self.analyzers[name] = analyzer_class
        self.logger.info(f"注册分析器: {name}")

    def get_analyzer(self, name: str) -> BaseAnalyzer:
        """获取分析器"""
        if name not in self.analyzers:
            raise ValueError(f"未找到分析器: {name}")
        return self.analyzers[name](self.db)

    def analyze(self, analysis_type: str, filters: AnalysisFilters) -> AnalysisResult:
        """执行分析"""
        try:
            analyzer = self.get_analyzer(analysis_type)
            analyzer.validate_filters(filters)
            result = analyzer.analyze_data(filters)
            return result
        except Exception as e:
            self.logger.error(f"分析失败 - 类型: {analysis_type}, 错误: {str(e)}")
            return AnalysisResult(
                success=False,
                data=None,
                message=f"分析失败: {str(e)}"
            )

    def get_available_analysis_types(self) -> List[str]:
        """获取可用的分析类型"""
        return list(self.analyzers.keys())

    def get_analysis_summary(self, filters: AnalysisFilters) -> Dict[str, Any]:
        """获取分析摘要"""
        summary = {}

        for analysis_type in self.analyzers.keys():
            try:
                analyzer = self.get_analyzer(analysis_type)
                basic_stats = analyzer.get_basic_statistics(filters)
                summary[analysis_type] = basic_stats
            except Exception as e:
                self.logger.warning(f"获取 {analysis_type} 统计失败: {str(e)}")
                summary[analysis_type] = {"error": str(e)}

        return summary


# 全局分析服务实例
_analysis_service = None

def get_analysis_service(db: Session = None) -> AnalysisService:
    """获取分析服务实例"""
    global _analysis_service

    if _analysis_service is None:
        if db is None:
            raise ValueError("首次调用需要提供数据库会话")
        _analysis_service = AnalysisService(db)

    return _analysis_service


def initialize_analysis_service(db: Session):
    """初始化分析服务"""
    service = get_analysis_service(db)

    # 这里可以注册各种分析器
    # 将在各个分析器模块中注册

    logger.info("分析服务初始化完成")
    return service